home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Format 1995 June
/
MacFormat 25.iso
/
Shareware City
/
Developers
/
ICProgKit1.0
/
Source
/
RandomSignature
/
ICRandomSignature.p
next >
Wrap
Text File
|
1994-11-27
|
14KB
|
498 lines
unit ICRandomSignature;
interface
uses
Components;
function Main (var params: ComponentParameters; storage: Handle): ComponentResult;
implementation
uses
{$ifc undefined THINK_Pascal}
Types, Files, QuickDraw, Aliases, Packages, Memory, Errors, ToolUtils, Resources,
ICTypes,
{$endc}
Folders, ICCAPI, ICKeys;
const
kOurComponentManufacturer = 'JMJ ';
function DecStr (l: longint): Str32;
var
tmpstr: Str255;
begin
NumToString(l, tmpstr);
DecStr := tmpstr;
end; (* DecStr *)
const
kICCStart = 0;
kICCStop = 1;
kICCFindConfigFile = 2;
kICCSpecifyConfigFile = 3;
kICCGetSeed = 4;
kICCBegin = 5;
kICCGetPref = 6;
kICCSetPref = 7;
kICCCountPref = 8;
kICCGetIndPref = 9;
kICCEnd = 10;
kICCDefaultFile = 11;
kICCDeletePref = 12;
kICCGetPerm = 13;
kICC_first_select = kICCStart;
kICC_last_select = kICCGetPerm;
type
globalsRecord = record
self: ComponentInstance;
target: ComponentInstance;
delegate: ComponentInstance;
current_signature: Handle;
default_signature: Handle;
sig_folder_name: Str63;
end;
globalsPtr = ^globalsRecord;
globalsHandle = ^globalsPtr;
sharedGlobals = record
delegate: Component;
end;
sharedGlobalsPtr = ^sharedGlobals;
function GetSharedGlobals (globals: globalsHandle): sharedGlobalsPtr;
var
shared: sharedGlobalsPtr;
begin
shared := nil;
if GetComponentInstanceA5(globals^^.self) = 0 then begin
shared := sharedGlobalsPtr(GetComponentRefcon(Component(globals^^.self)));
end
else begin
(* Debugger; *)
(* This, needless to say, is not the correct answer. You're support to go madly search for the component. *)
(* I just can't be bothered to deal with this at the moment. *)
end; (* if *)
GetSharedGlobals := shared;
end; (* GetSharedGlobals *)
(* Component Manager routines *)
function RSCRegister (globals: globalsHandle): ComponentResult;
var
shared: sharedGlobalsPtr;
err: OSErr;
junk: OSErr;
begin
junk := SetDefaultComponent(Component(globals^^.self), defaultComponentIdentical + defaultComponentAnyFlags);
shared := sharedGlobalsPtr(NewPtrSysClear(sizeof(sharedGlobals)));
err := MemError;
if err = noErr then begin
shared^.delegate := nil;
SetComponentRefcon(Component(globals^^.self), longint(shared));
end; (* if *)
RSCRegister := err;
end; (* RSCRegister *)
function RSCUnregister (globals: globalsHandle): ComponentResult;
var
shared: sharedGlobalsPtr;
result: ComponentResult;
begin
result := -1;
shared := GetSharedGlobals(globals);
if shared <> nil then begin
result := UncaptureComponent(shared^.delegate);
DisposePtr(Ptr(shared));
end; (* if *)
RSCUnregister := result;
end; (* RSCUnregister *)
function RSCCanDo (globals: globalsHandle; selector: integer): ComponentResult;
(* Handle the Component Manager CanDo request.*)
begin
case selector of
kComponentUnregisterSelect..kComponentOpenSelect:
RSCCanDo := 1;
otherwise
RSCCanDo := ComponentFunctionImplemented(globals^^.delegate, selector);
end; (* case *)
end; (* RSCCanDo *)
function FindDelegate (after: Component): Component;
var
cd: ComponentDescription;
found_cd: ComponentDescription;
current: Component;
found: boolean;
begin
cd.componentType := internetConfigurationComponentType;
cd.componentSubType := internetConfigurationComponentSubType;
cd.componentManufacturer := OSType(0);
cd.componentFlags := 0;
cd.componentFlagsMask := 0;
current := after;
repeat
(* DebugStr(concat('in loop for ', kOurComponentManufacturer)); *)
current := FindNextComponent(current, cd);
if current <> nil then begin
if GetComponentInfo(current, found_cd, nil, nil, nil) = noErr then begin
found := (found_cd.componentManufacturer <> kOurComponentManufacturer);
end; (* if *)
end; (* if *)
until found or (current = nil);
FindDelegate := current;
end; (* FindDelegate *)
function InitGlobals (globals: globalsHandle): ComponentResult;
var
err: ComponentResult;
refnum: integer;
strh: StringHandle;
junk: OSErr;
begin
err := noErr;
refnum := OpenComponentResFile(Component(globals^^.self));
if refnum <= 0 then begin
err := resNotFound;
end; (* if *)
if err = noErr then begin
strh := GetString(130);
if strh = nil then begin
err := resNotFound;
end
else begin
globals^^.sig_folder_name := strh^^;
end; (* if *)
if err = noErr then begin
globals^^.default_signature := Get1Resource('TEXT', 128);
if globals^^.default_signature = nil then begin
err := resNotFound;
end
else begin
DetachResource(globals^^.default_signature);
end; (* if *)
globals^^.current_signature := nil;
end; (* if *)
junk := CloseComponentResFile(refnum);
end; (* if *)
InitGlobals := err;
end; (* InitGlobals *)
function RSCOpen (globals: globalsHandle; self: ComponentInstance): ComponentResult;
(* Handle the Component Manager Open request, mostly delayed until ICCStart. *)
var
err: ComponentResult;
cap: Component;
shared: sharedGlobalsPtr;
tmp: Component;
begin
(* create our globals *)
globals := globalsHandle(NewHandleClear(sizeof(globalsRecord)));
err := MemError;
if err = noErr then begin
HLock(Handle(globals));
(* Debugger; *)
globals^^.self := self;
SetComponentInstanceStorage(self, Handle(globals));
shared := GetSharedGlobals(globals);
if shared <> nil then begin
if shared^.delegate = nil then begin
tmp := FindDelegate(Component(self));
if tmp <> nil then begin
shared^.delegate := CaptureComponent(tmp, Component(self));
end; (* if *)
end; (* if *)
globals^^.delegate := OpenComponent(shared^.delegate);
err := ComponentSetTarget(self, self);
end; (* if *)
if err = noErr then begin
err := InitGlobals(globals);
end; (* if *)
HUnlock(Handle(globals));
end; (* if *)
RSCOpen := err;
end; (* RSCOpen *)
function RSCClose (globals: globalsHandle; self: ComponentInstance): ComponentResult;
(* Handle the Component Manager Close request. *)
var
err: ComponentResult;
junk: OSErr;
begin
err := noErr;
if globals <> nil then begin
if globals^^.delegate <> nil then begin
junk := CloseComponent(globals^^.delegate)
end; (* if *)
DisposeHandle(Handle(globals));
end; (* if *)
RSCClose := err;
end; (* RSCClose *)
function RSCTarget (globals: globalsHandle; new_target: ComponentInstance): ComponentResult;
(* Handle the Component Manager Target. *)
var
err: ComponentResult;
begin
globals^^.target := new_target;
if globals^^.delegate <> nil then begin
err := ComponentSetTarget(globals^^.delegate, new_target);
end
else begin
err := noErr;
end; (* if *)
RSCTarget := err;
end; (* RSCTarget *)
(* Internet Configuration specific routines *)
function GetRandomSignature (globals: globalsHandle): Handle;
var
cpb: CInfoPBRec;
sig: FSSpec;
function GetNthTextFile (max_count: integer; var count: integer): OSErr;
var
err: OSErr;
index: integer;
begin
count := 0;
index := 1;
repeat
cpb.ioNamePtr := @sig.name;
cpb.ioDirID := sig.parID;
cpb.ioVRefNum := sig.vRefNum;
cpb.ioFDirIndex := index;
err := PBGetCatInfoSync(@cpb);
index := index + 1;
if (err = noErr) and not btst(cpb.ioFlAttrib, 4) and (cpb.ioFlFndrInfo.fdType = 'TEXT') then begin
count := count + 1;
end; (* if *)
until (err <> noErr) or (count = max_count);
GetNthTextFile := err;
end; (* GetNthTextFile *)
var
junk: OSErr;
texth: Handle;
err: OSErr;
ref: integer;
count: integer;
length: longint;
begin
texth := nil;
sig.name := globals^^.sig_folder_name;
err := FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, sig.vRefNum, sig.parID);
if err = noErr then begin
cpb.ioNamePtr := @sig.name;
cpb.ioVRefNum := sig.vRefNum;
cpb.ioDirID := sig.parID;
cpb.ioFDirIndex := 0;
err := PBGetCatInfoSync(@cpb);
end; (* if *)
if (err = noErr) and not btst(cpb.ioFlAttrib, 4) then begin
err := dirNFErr;
end; (* if *)
if err = noErr then begin
sig.parID := cpb.ioDirID;
junk := GetNthTextFile(32767, count);
if count = 0 then begin
err := fnfErr;
end
else begin
count := (abs(random) mod count) + 1;
err := GetNthTextFile(count, junk);
end; (* if *)
end; (* if *)
if err = noErr then begin
err := HOpen(sig.vRefNum, sig.parID, sig.name, fsRdPerm, ref);
end; (* if *)
if err = noErr then begin
err := GetEOF(ref, length);
if err = noErr then begin
if length > 4096 then begin
length := 4096;
end; (* if *)
texth := NewHandle(length);
err := MemError;
end; (* if *)
if err = noErr then begin
err := FSRead(ref, length, texth^);
end; (* if *)
junk := FSClose(ref);
end; (* if *)
if err <> noErr then begin
DisposeHandle(texth);
texth := nil;
end; (* if *)
if texth = nil then begin
texth := globals^^.default_signature;
err := HandToHand(texth);
if err <> noErr then begin
texth := nil;
end; (* if *)
end; (* if *)
GetRandomSignature := texth;
end; (* GetRandomSignature *)
procedure ChooseRandomSignature (globals: globalsHandle);
begin
if globals^^.current_signature <> nil then begin
DisposeHandle(globals^^.current_signature);
end; (* if *)
globals^^.current_signature := GetRandomSignature(globals);
end; (* ChooseRandomSignature *)
const
delegateThisCallErr = 1;
function RSCBegin (globals: globalsHandle; perm: ICPerm): ICError;
var
err: ICError;
begin
ChooseRandomSignature(globals);
RSCBegin := delegateThisCallErr;
end; (* RSCBegin *)
function RSCGetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
var
tmpstr: Str255;
perm: icPerm;
max_size: longint;
err: ICError;
begin
if IUEqualString(key, kICSignature) = 0 then begin
if (ICCGetPerm(globals^^.delegate, perm) = noErr) & (perm = icNoPerm) then begin
ChooseRandomSignature(globals);
end; (* if *)
max_size := size;
if globals^^.current_signature = nil then begin
size := 0;
end
else begin
size := GetHandleSize(globals^^.current_signature);
end; (* if *)
err := noErr;
if ((max_size < 0) and (buf <> nil)) then begin
err := paramErr;
end; (* if *)
if (err = noErr) and (buf <> nil) then begin
if size > max_size then begin
err := icTruncatedErr;
end
else begin
max_size := size;
end; (* if *)
if max_size <> 0 then begin
BlockMove(globals^^.current_signature^, buf, max_size);
end; (* if *)
end; (* if *)
attr := ICattr_locked_mask + ICattr_volatile_mask;
RSCGetPref := err;
end
else begin
RSCGetPref := delegateThisCallErr;
end; (* if *)
end; (* RSCGetPref *)
function RSCSetPref (globals: globalsHandle; key: Str255; var attr: ICAttr; buf: Ptr; var size: longint): ICError;
begin
if IUEqualString(key, kICSignature) = 0 then begin
RSCSetPref := icPermErr;
end
else begin
RSCSetPref := delegateThisCallErr;
end; (* if *)
end; (* RSCSetPref *)
function WhatToStr (what: integer): Str32;
begin
case what of
(* Component Manager stuff *)
kComponentVersionSelect:
WhatToStr := 'kComponentVersionSelect';
kComponentCanDoSelect:
WhatToStr := 'kComponentCanDoSelect';
kComponentOpenSelect:
WhatToStr := 'kComponentOpenSelect';
kComponentCloseSelect:
WhatToStr := 'kComponentCloseSelect';
kComponentTargetSelect:
WhatToStr := 'kComponentTargetSelect';
kComponentRegisterSelect:
WhatToStr := 'kComponentRegisterSelect';
kComponentUnregisterSelect:
WhatToStr := 'kComponentUnregisterSelect';
(* this component type stuff *)
kICCGetPref:
WhatToStr := 'kICCGetPref';
kICCSetPref:
WhatToStr := 'kICCSetPref';
otherwise
WhatToStr := 'other';
end; (* case *)
end; (* WhatToStr *)
function Main (var params: ComponentParameters; storage: Handle): ComponentResult;
(* Component entry point. It's pretty neat IMHO. *)
var
proc: ProcPtr;
s: signedByte;
res: longint;
begin
proc := nil;
(* DebugStr(concat('Enter ', WhatToStr(params.what))); *)
case params.what of
(* Component Manager stuff *)
kComponentVersionSelect:
Main := internetConfigurationComponentInterfaceVersion;
kComponentCanDoSelect:
proc := @RSCCanDo;
kComponentOpenSelect:
proc := @RSCOpen;
kComponentCloseSelect:
proc := @RSCClose;
kComponentTargetSelect:
proc := @RSCTarget;
kComponentRegisterSelect:
proc := @RSCRegister;
kComponentUnregisterSelect:
proc := @RSCUnregister;
(* this component type stuff *)
kICCBegin:
proc := @RSCBegin;
kICCGetPref:
proc := @RSCGetPref;
kICCSetPref:
proc := @RSCSetPref;
otherwise
;
end; (* case *)
if storage <> nil then begin
s := HGetState(storage);
HLock(storage);
end; (* if *)
res := delegateThisCallErr;
if proc <> nil then begin
res := CallComponentFunctionWithStorage(storage, params, proc);
end; (* if *)
if res = delegateThisCallErr then begin
res := DelegateComponentCall(params, globalsHandle(storage)^^.delegate);
end; (* if *)
(* DebugStr(concat('Exit ', WhatToStr(params.what), ' with res ', DecStr(res))); *)
Main := res;
if storage <> nil then begin
HSetState(storage, s);
end; (* if *)
end; (* Main *)
end. (* ICRandomSignature *)